package saas.adapter.sdk.core.interceptor;

import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import saas.adapter.sdk.constant.Constants;
import saas.adapter.sdk.core.context.TenantConversionRelationHolder;
import saas.adapter.sdk.entity.TenantConversionRelation;
import saas.adapter.sdk.init.TenantConversionRelationInitializer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.Objects;

/**
 * @title: InboundHttpConversionTenantInterceptor
 * @description: Http方式入口租户转换拦截器（本系统接收外部http请求）
 * @author: guan.xin
 * @create: 2021-11-12 09:57
 * @since: JDK8
 */
@Slf4j
public class InboundHttpConversionTenantInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // request头部获取中台租户编码
        String mpSaasTenantCode = request.getHeader(Constants.SAAS_TENANT_CODE_FIELD);
        if (Strings.isNullOrEmpty(mpSaasTenantCode)) {
            log.warn("请求url：{}，saasTenantCode为空", request.getRequestURI());
        } else {
            // 中台租户编码 映射 OMS租户编码
            TenantConversionRelation tenantConversionRelation = TenantConversionRelationInitializer.getTenantConversionRelationByMpTenantCode(mpSaasTenantCode);

            // 映射配置校验（warn）
            if (Objects.isNull(tenantConversionRelation)
                    || Strings.isNullOrEmpty(tenantConversionRelation.getOmsTenantCode())) {
                log.warn("请求url：{}, saasTenantCode：{}, 无法映射OMS租户信息", request.getRequestURI(), mpSaasTenantCode);
            } else {
                // 重置request头部租户编码
                log.info("请求url：{}, saasTenantCode：{}, 成功映射OMS租户信息, OMS租户：{}", request.getRequestURI(), mpSaasTenantCode, tenantConversionRelation.getOmsTenantCode());
                resetHeader(request, Constants.SAAS_TENANT_CODE_FIELD, tenantConversionRelation.getOmsTenantCode());

                // 设置租户转换关系上下文
                TenantConversionRelationHolder.set(tenantConversionRelation);
            }
        }

        return true;
    }

    /**
     * 重置request请求header信息
     *
     * @param request
     * @param name
     * @param value
     */
    private void resetHeader(HttpServletRequest request, String name, String value) {
        Class<? extends HttpServletRequest> requestClass = request.getClass();
        try {
            Field requestFiled = requestClass.getDeclaredField("request");
            requestFiled.setAccessible(true);
            Object o = requestFiled.get(request);
            Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);
            Object coyoteRequestObject = coyoteRequest.get(o);
            Field headers = coyoteRequestObject.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders mimeHeaders = (MimeHeaders) headers.get(coyoteRequestObject);
            mimeHeaders.removeHeader(name);
            mimeHeaders.addValue(name).setString(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
